package org.hxzon.tapestry5.services;

import java.util.concurrent.atomic.AtomicBoolean;

import org.apache.commons.io.FileCleaningTracker;
import org.apache.tapestry5.ioc.MappedConfiguration;
import org.apache.tapestry5.ioc.OrderedConfiguration;
import org.apache.tapestry5.ioc.ScopeConstants;
import org.apache.tapestry5.ioc.ServiceBinder;
import org.apache.tapestry5.ioc.annotations.Autobuild;
import org.apache.tapestry5.ioc.annotations.InjectService;
import org.apache.tapestry5.ioc.annotations.Scope;
import org.apache.tapestry5.ioc.services.RegistryShutdownHub;
import org.apache.tapestry5.services.HttpServletRequestFilter;
import org.apache.tapestry5.upload.internal.services.MultipartDecoderImpl;
import org.apache.tapestry5.upload.services.MultipartDecoder;
import org.hxzon.tapestry5.internal.AjaxUploadServletRequestFilter;
import org.hxzon.tapestry5.internal.services.AjaxUploadDecoderImpl;

public class AjaxUploadModule {
    private static final AtomicBoolean needToAddShutdownListener = new AtomicBoolean(true);

    public static void bind(ServiceBinder binder) {
        binder.bind(AjaxUploadDecoder.class, AjaxUploadDecoderImpl.class).scope(ScopeConstants.PERTHREAD);
    }

    @Scope(ScopeConstants.PERTHREAD)
    public static MultipartDecoder buildMultipartDecoder2(//
            RegistryShutdownHub shutdownHub, //
            @Autobuild MultipartDecoderImpl multipartDecoder) {

        if (needToAddShutdownListener.getAndSet(false)) {
            shutdownHub.addRegistryShutdownListener(new Runnable() {
                @Override
                public void run() {
                    new FileCleaningTracker().exitWhenFinished();//?
                }
            });
        }

        return multipartDecoder;
    }

    public static void contributeServiceOverride(//
            @InjectService("MultipartDecoder2") MultipartDecoder multipartDecoder, //
            @SuppressWarnings("rawtypes") MappedConfiguration<Class, Object> overrides) {
        overrides.add(MultipartDecoder.class, multipartDecoder);
    }

    public static void contributeHttpServletRequestHandler(//
            OrderedConfiguration<HttpServletRequestFilter> configuration, //
            AjaxUploadDecoder ajaxUploadDecoder) {
        configuration.add("AjaxUploadFilter", new AjaxUploadServletRequestFilter(ajaxUploadDecoder), "after:IgnoredPaths");
    }

}
